home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / QuickDraw™ GX / Programming Stuff / Sample Code / Graphics Samples / viewPort Mania ƒ / graphics shell.c next >
Encoding:
C/C++ Source or Header  |  1995-04-10  |  13.2 KB  |  405 lines  |  [TEXT/KAHL]

  1. /**\
  2. |**| =====================================================================
  3. |**|
  4. |**|    graphics shell.c
  5. |**|
  6. |**|    This file is a shell that can be used to build "new" Graphics 
  7. |**|    applications.  It contains all of the required calls to use the "new"
  8. |**|    Graphics routines and QuickDraw (i.e. windows) together. You "quit" the
  9. |**|    application by clicking in the close box.  This shell does not use a menu.
  10. |**|
  11. |**|    The application is expected to supply the following functions which
  12. |**|    are called by this shell:
  13. |**|        void DoInitialization (WindowPtr);
  14. |**|        void DoDraw (WindowPtr);
  15. |**|        void DoDispose (WindowPtr);
  16. |**|        void DoClick (gxPoint, WindowPtr);
  17. |**|        void DoIdle (WindowPtr);
  18. |**|
  19. |**|
  20. |**|    Change History:
  21. |**|        3/90    New
  22. |**|        6/91    PLA  Updated the shell to reflect the changes in
  23. |**|                     "Graphics" v1.0d21.2.
  24. |**|        6/92    PLA  Made the following variables global: gDebugging,
  25. |**|                     gGiveMeValidation,gGraphicsHeapSize.
  26. |**|                     See the comments for detail in this file.
  27. |**|        9/93    PLA  Updated files to work with the ß2 "GXified"
  28. |**|                     interface files.
  29. |**|                     Worked around a problem with GXConvertQDPoint(..)
  30. |**|                     see the comments within the GetWindowBoundsShape(..)
  31. |**|                     call for details (below).
  32. |**|        12/93    PLA  Updated the comment above the GXNewGraphicsCLient call
  33. |**|                     to reflect the new fucntionality of this call in ß3. 
  34. |**|                     Removed the work around with GXConvertQDPoint (..)
  35. |**|                     where the call would not survive validation under ß2.
  36. |**|                     Under ß3 the call suceeds when validation is set.   PLA
  37. |**|        3/94    PLA  Removed the following varaibles: gDebugging &
  38. |**|                     gGiveMeValidation see the comments for details (below). 
  39. |**|                     Added a Gestalt check to see if GX has been installed.
  40. |**|                     Added extensive error checking to make sure the GX graphics
  41. |**|                     client has been created and the GX heap correctly allocated.
  42. |**|                     This shell will shut down at start-up and alert the user
  43. |**|                     to the problem and bail if: GX is not installed, we cannot
  44. |**|                     create the graphics client, or create a GX heap.
  45. |**|        4/94    PLA  Added the gxPoint as a parameter to the DoClick (..)
  46. |**|                     function to support hit testing. 
  47. |**|                     Added a check to see if the PowerPC QuickDrawGXLib is
  48. |**|                     installed. Search on "powerc" to find all of the changes
  49. |**|                     added to support Native QuickDraw GX on a Power Mac.  PLA
  50. |**|        8/94    DH   More changes made for universal header and clarity
  51. |**|                     Removed GetWindowBoundsShape(..) since it wasn't being
  52. |**|                     used after the workaround was removed 19/93
  53. |**|
  54. |**|    ©1990-1994  Apple Computer, Inc.
  55. |**|    All rights reserved.
  56. |**|
  57. |**| =====================================================================
  58. \**/
  59.  
  60.  
  61.  
  62. #include "graphics shell.h"
  63.  
  64.  
  65. /**\
  66. |**| ---------------------------------------------------------------------
  67. |**| ENUMS
  68. |**| ---------------------------------------------------------------------
  69. \**/
  70. enum { rWindResource = 128 };
  71.  
  72.  
  73. /**\
  74. |**| ---------------------------------------------------------------------
  75. |**| GLOBALS
  76. |**| ---------------------------------------------------------------------
  77. \**/
  78. Boolean            gQuitting = false;
  79. long            gSleep = 0;
  80. WindowPtr         gWindow;
  81. gxViewPort        gTheWindowsViewPort;    
  82.  
  83. #if defined(powerc) && !defined(__MWERKS__)
  84. QDGlobals        qd;
  85. #endif
  86.  
  87.  
  88.  
  89. /**\
  90. |**| ---------------------------------------------------------------------
  91. |**| main()
  92. |**| ---------------------------------------------------------------------
  93. \**/
  94. void main()
  95. {        
  96.     CursHandle            theCurs; 
  97.     long                theFeature;
  98.     Boolean                debuggingInitInstalled = false;
  99.     gxGraphicsClient     client;
  100.     
  101.     InitToolbox();
  102.     
  103.     theCurs = GetCursor(watchCursor);
  104.     SetCursor(*theCurs);
  105.  
  106.     CheckQuickDrawGX();
  107.     if (gQuitting)
  108.     {
  109.         SetCursor(&qd.arrow);
  110.         (void) StopAlert(rNoQuickDrawGXID, NULL);
  111.         return;
  112.     }
  113.  
  114.  
  115.     //
  116.     //    The QuickDraw GX gestaltGraphicsAttr Gestalt attribute can be used to determine if:
  117.     //    the graphics piece of GX has been loaded, the QuickDrawGX debugging init is installed,
  118.     //    or your are running the PowerPC version. 
  119.     //
  120.     //    In our case, we only need to know if the debugging init was installed. If it is,
  121.     //    we will enable the QuickDraw GX validation and notice handling features.We define 
  122.     //    debuggingInitInstalled as true to enable GX validation and notice handler
  123.     //  within the SetUpGXDebuggingWorld function.
  124.     //
  125.     if ( (Gestalt(gestaltGraphicsAttr, &theFeature) == noErr) )
  126.         if ( (theFeature & gestaltGraphicsIsDebugging) == gestaltGraphicsIsDebugging ) 
  127.          debuggingInitInstalled = true;
  128.     
  129.     
  130.     client = GXNewGraphicsClient(nil, gGraphicsHeapSize * 1024, 0L);
  131.     
  132.     //
  133.     //    After we attempted to create the graphics client, we need to determine if the call
  134.     //  succeeded. If the call did not (as in the case for all GX functions), "client" will
  135.     //    be nil. If it is, we alert the user to the problem. Otherwise, we will attempted to 
  136.     //    allocate the GX heap below...
  137.     
  138.     if ( client ) 
  139.     {
  140.         //    Initialize the new graphics environment and create the GX heap.
  141.         
  142.         GXEnterGraphics();
  143.     
  144.         //
  145.         //    Calling GXEnterGraphics allocates the memory within the GX heap. The only reason the
  146.         //  call would not succeed is if there is not enough memory. In this case, the graphics 
  147.         //  error which will be posted is -27999 (out of memory). At this point, we have not 
  148.         //    installed an error handler, so we check for the error number corresponding to the 
  149.         //  out of memory error.
  150.         
  151.         if ( GXGetGraphicsError( nil ) != out_of_memory ) 
  152.         {
  153.             SetUpGXDebuggingWorld (debuggingInitInstalled);
  154.      
  155.             //
  156.             //    Create a window and attach a GX viewPort to it. By attaching the viewPort to 
  157.             //    the window will make sure that when a user moves or resizes the window all of
  158.             //    the GX drawing will occur within window. 
  159.             //
  160.             //    By the way, you cannot directly manipulate the parent viewPort attached to the
  161.             //    window, you will recieve a graphics error. This viewPort can only be manipulated
  162.             //  by the GX system. If you want to manipulate a viewPort attached to a window, it
  163.             //     _must_ be a child viewPort attached to the the parent viewPort attached to the
  164.             //    window.
  165.             
  166.             gWindow = GetNewWindow(rWindResource, nil, (WindowPtr)-1L);
  167.                                                  
  168.             gTheWindowsViewPort = GXNewWindowViewPort(gWindow);
  169.     
  170.             GXIgnoreGraphicsNotice(transform_already_set);
  171.             SetDefaultViewPort(gTheWindowsViewPort);
  172.             GXPopGraphicsNotice();
  173.     
  174.             
  175.             //    Create the GX shapes we are going to draw to the window. 
  176.             
  177.             DoInitialization(gWindow);
  178.     
  179.             SetCursor(&qd.arrow);  
  180.     
  181.             while (!gQuitting)
  182.                 EventLoop();           // loop until the window is closed
  183.     
  184.             // Leaving.  Close all the windows so we get rid of any data we or GX created.  Then,
  185.             // dispose of the common colors and exit the GX printing and graphics environment.
  186.     
  187.             DoDispose(gWindow);
  188.     
  189.             GXExitGraphics();     // Deallocate all of the default structures
  190.     
  191.         } else   DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");                
  192.     }  else   DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");
  193.         
  194.     GXDisposeGraphicsClient(client);
  195. }
  196.  
  197.  
  198.  
  199. /**\
  200. |**| ---------------------------------------------------------------------
  201. |**| InitToolbox()
  202. |**| ---------------------------------------------------------------------
  203. \**/
  204. void InitToolbox (void)
  205. {
  206.     // Generic heap initialization.
  207.     
  208.     MaxApplZone(); 
  209.     MoreMasters(); MoreMasters(); MoreMasters(); 
  210.     MoreMasters(); MoreMasters(); MoreMasters(); 
  211.     
  212.     // Start up the toolbox so we can notify people if there's a problem
  213.     
  214.     InitGraf(&qd.thePort);
  215.     InitFonts();
  216.     InitWindows();
  217.     InitDialogs(nil);
  218.     InitCursor();
  219. }
  220.  
  221.  
  222. /**\
  223. |**| ---------------------------------------------------------------------
  224. |**| CheckQuickDrawGX()
  225. |**| Before making any calls, we'll see if QuickDraw GX is available.
  226. |**| If it's not, then set gQuitting=true so we can avoid doing any of 
  227. |**| the rest of this application.
  228. |**| ---------------------------------------------------------------------
  229. \**/
  230. void CheckQuickDrawGX (void)
  231. {
  232.     long                theFeature;
  233.  
  234.     // Before making any calls, we'll see if QuickDraw GX is available.  If it's not,
  235.     // we'll avoid doing any of the rest of this application
  236.     
  237.     if (Gestalt(gestaltGraphicsVersion, &theFeature) != noErr)
  238.         gQuitting = true;   // QuickDraw GX is not available
  239.     
  240. #ifdef powerc
  241.     // This is a sanity check to see if the PowerPC QuickDrawGXLib is installed.
  242.     // Since we are "weak" linked to QuickDrawGXLib, the Process Manager will
  243.     // launch us even if QuickDrawGXLib is missing.  If it's missing, the
  244.     // Code Fragment Manager will leave the address of the functions we call
  245.     // unresolved, and we would crash if we tried to call that function.  So,
  246.     // we do a check here and should be prepared to exit gracefully if the 
  247.     // library is missing.  This could happen if the user has installed a
  248.     // 68K only version of QuickDraw GX.  It could also happen if the user has
  249.     // taken the QuickDraw GX extension out of the Extensions Folder.  
  250.     //
  251.     // Note - We could check this against any function we call in the library.
  252.     // GXNewGraphicsClient is the first function we call, so it's convenient.
  253.  
  254.     if ( (Ptr)GXNewGraphicsClient == kUnresolvedSymbolAddress ) 
  255.         gQuitting = true;   // QuickDraw GX is not available in Power Mac
  256. #endif
  257. }
  258.  
  259.  
  260. /**\
  261. |**| ---------------------------------------------------------------------
  262. |**| SetUpGXDebuggingWorld()
  263. |**| This function enables the GX error handling capabilities and validation
  264. |**| routines.  The validation routines are only enabled, if the user has  
  265. |**| installed the QuickDraw GX debugging init.  These routines are not
  266. |**| available with the non-debugging init. Calling them when they are not  
  267. |**| installed will not cause any problems, but it will cause unnecessary
  268. |**| work to be done by your application and the GX dispatcher.
  269. |**| ---------------------------------------------------------------------
  270. \**/
  271. void SetUpGXDebuggingWorld (Boolean debuggingInitInstalled)
  272. {
  273.       // 
  274.     //    We set-up GX validation, if the user has installed the "GXGraphics (debug)" init (formerly
  275.     //    named "aSecretGraphics.debug). This validation setting is the reccommended setting while
  276.     //    you are developing your GX application. As you increase the amount of validation, the drawing
  277.     //    speed will SLOW down due to all of the internal checking. 
  278.     //
  279.     //    For additional details regarding the various levels of validation, please see the
  280.     //    QuickDraw GX : Environment & Utilities book.
  281.     //
  282.     if ( debuggingInitInstalled ) GXSetValidation(gxPublicValidation + gxTypeValidation); 
  283.  
  284.     // 
  285.     //    Calling SetGraphicsLibraryErrors will install a GX error and warning handler. This
  286.     //    call is provided by the QuickDraw GX "graphics debugging library". Any time a GX error
  287.     //    or warning is generated, it will be posted to Macsbug.
  288.     //
  289.     SetGraphicsLibraryErrors ();
  290.         
  291.     //
  292.     //    If the user has installed the GX debugging version, we install a notice handler. Why? The
  293.     //    GX notice handling capabilities are only available with the debugging version.
  294.     //
  295.     if ( debuggingInitInstalled ) SetGraphicsLibraryNotices();
  296. }
  297.  
  298.  
  299.  
  300. /**\
  301. |**| ---------------------------------------------------------------------
  302. |**| EventLoop()
  303. |**| ---------------------------------------------------------------------
  304. \**/
  305. void EventLoop ()
  306. {
  307.     EventRecord event;
  308.  
  309.     if ( WaitNextEvent(everyEvent, &event, gSleep, nil) )
  310.         MyDoEvent(&event);
  311.     else
  312.         DoIdle(FrontWindow());
  313. }
  314.  
  315.  
  316. /**\
  317. |**| ---------------------------------------------------------------------
  318. |**| MyDoEvent()
  319. |**| ---------------------------------------------------------------------
  320. \**/
  321. void MyDoEvent (EventRecord *event)
  322. {
  323.     WindowPtr         window;        // temporarily used to hold 
  324.     GrafPtr            oldPort;
  325.     unsigned long    mssg;
  326.  
  327.     mssg = event->message;
  328.     switch(event->what)
  329.     {                    
  330.         case updateEvt:
  331.             BeginUpdate((WindowPtr) mssg);
  332.             SetPort(gWindow);
  333.             DoDraw(gWindow);
  334.             EndUpdate((WindowPtr) mssg);
  335.             break;
  336.  
  337.         case mouseDown:
  338.             DoMouseDown(event);
  339.             break;
  340.  
  341.         case osEvt:
  342.             if ( (mssg>>24)                        // if high byte of message indicates
  343.                     == suspendResumeMessage )    // this is suspend/resume event
  344.             {
  345.                 if (mssg & resumeFlag)            // if resume event
  346.                     gSleep = 0;                    // we're switching back from another app so speed up  
  347.                 else                            // if suspend event
  348.                     gSleep = 80;                // we're switching to another app so slow down...
  349.             }
  350.             break;
  351.                     
  352.     }
  353. }
  354.  
  355.  
  356. /**\
  357. |**| ---------------------------------------------------------------------
  358. |**| DoMouseDown
  359. |**| handle DoMouseDown events
  360. |**| ---------------------------------------------------------------------
  361. \**/
  362. void DoMouseDown (EventRecord *event)
  363. {
  364.     WindowPtr   window;
  365.     short       clickArea;
  366.     Rect        screenRect;
  367.  
  368.     clickArea = FindWindow( event->where, &window );
  369.     switch (clickArea)
  370.     {
  371.         case inSysWindow:
  372.             SystemClick(event, window);
  373.             break;
  374.                         
  375.         case inDrag:
  376.             screenRect = (**GetGrayRgn()).rgnBBox;
  377.                 DragWindow( window, event->where, &screenRect );
  378.             break;
  379.  
  380.         case inContent:
  381.             if ( window == FrontWindow())
  382.             {
  383.                  gxPoint        mouseLoc;
  384.                  Point        currMouseLoc;
  385.                  
  386.                  currMouseLoc.h = event->where.h;
  387.                  currMouseLoc.v = event->where.v;
  388.                  
  389.                 GXConvertQDPoint(&currMouseLoc, gTheWindowsViewPort, &mouseLoc);
  390.  
  391.                  DoClick(mouseLoc, gWindow);
  392.             }
  393.             else
  394.                  SelectWindow(window);
  395.             break;
  396.         
  397.         case inGoAway:
  398.             if ( TrackGoAway(window, event->where) )
  399.                 gQuitting = true;
  400.             break;
  401.         
  402.     }
  403. }
  404.             
  405.